@extends('Admin.layout')
@section('main')
    <el-card class="box-card" style="margin-bottom: 5px">
        <el-row :gutter="5">
            <el-col :span="2">
                <el-checkbox v-model="make.isPlugins" border @change="isPluginsChange" label="插件"></el-checkbox>
            </el-col>
            <el-col :span="3" v-if="make.isPlugins">
                <el-autocomplete clearable :fetch-suggestions="pluginsQuerySearch" @change="pluginsChange"
                                 @select="pluginsSelected" v-model="make.plugins">
                    <template #default="{ item }">
                        @{{ item.name }}
                    </template>
                </el-autocomplete>
            </el-col>
            <el-col :span="6">
                <el-form-item :label-width="120" label="来源数据表:">
                    <el-autocomplete value-key="TABLE_NAME" clearable @select="tableSelected"
                                     :fetch-suggestions="tableQuerySearch" v-model="make.table" placeholder="表名">
                        <template #default="{ item }">
                            @{{item.TABLE_NAME}} @{{item.TABLE_COMMENT}}
                        </template>
                    </el-autocomplete>
                </el-form-item>
            </el-col>
            <el-col :span="5">
                <el-form-item label="子文件夹:">
                    <el-autocomplete clearable :fetch-suggestions="dirQuerySearch" @select="dirSelected"
                                     @change="checkFiles" v-model="make.dir" placeholder="文件夹：Adri/Bdir">
                        <template #default="{ item }">
                            @{{ item }}
                        </template>
                    </el-autocomplete>
                </el-form-item>
            </el-col>
            <el-col :span="2">
                <el-checkbox v-model="make.isCover" border label="覆盖"></el-checkbox>
            </el-col>
            <el-col :span="5">
                <el-button type="success" @click="submit" v-loading="submitLoading">提交创建</el-button>
            </el-col>
            <el-col :span="22">
                <el-form-item style="background-color: #fde2e2" v-if="existsFiles.length > 0" :label-width="120"
                              label="已存在文件: ">
                    <el-checkbox-group v-model="clearExistsFiles">
                        <el-checkbox v-for="file in existsFiles" :key="file.mode" :label="file.filename">@{{ file.mode
                            }}
                        </el-checkbox>
                    </el-checkbox-group>
                </el-form-item>
            </el-col>
            <el-col :span="2">
                <el-button v-if="existsFiles.length > 0" type="primary" @click="clearFile" v-loading="clearLoading">
                    清除选中文件
                </el-button>
            </el-col>
            <el-col :span="4">
                <el-form-item :label-width="120" label="要创建的文件: ">
                    <el-checkbox v-model="fileAll" :indeterminate="isIndeterminate" @change="handleCheckAllChange">
                        全部
                    </el-checkbox>
                </el-form-item>
            </el-col>
            <el-col :span="20">
                <el-checkbox-group v-model="make.files" @change="handleCheckedCitiesChange">
                    <el-checkbox v-for="file in waitFile" :key="file.sign" :label="file.sign">@{{ file.title }}
                    </el-checkbox>
                </el-checkbox-group>
            </el-col>
            <el-col :span="4">
                <el-form-item v-if="make.files.includes('Controller')" :label-width="120" label="控制器方法: ">
                    <el-checkbox v-model="methodAll" :indeterminate="methodIsIndeterminate"
                                 @change="methodHandleCheckAllChange">全部
                    </el-checkbox>
                </el-form-item>
            </el-col>
            <el-col :span="20">
                <el-checkbox-group v-if="make.files.includes('Controller')" v-model="make.controllerMethod"
                                   @change="methodHandleCheckedCitiesChange">
                    <el-checkbox v-for="method in controllerMethod" :key="method.value" :label="method.value">
                        @{{ method.title }}
                        <el-text v-if="method.view" type="warning">[view]</el-text>
                    </el-checkbox>
                </el-checkbox-group>
            </el-col>
            <el-col :span="24"
                    v-if="make.controllerMethod.filter(v => controllerMethod.filter(v1 => v1.view).map(v1 => v1.value).includes(v)).length > 0">
                <el-form-item :label-width="120" label="视图类型:">
                    <el-radio-group v-model="make.viewType" @change="handleCheckedCitiesChange">
                        <el-radio :key="1" label="sc">默认(sc)</el-radio>
                        <el-radio :key="2" label="blade" disabled="">blade</el-radio>
                    </el-radio-group>
                </el-form-item>
            </el-col>
            <el-col :span="10"
                    v-if="make.controllerMethod.filter(v => controllerMethod.filter(v1 => v1.view).map(v1 => v1.value).includes(v)).length > 0">
                <el-form-item :label-width="120" label="子页面类型:">
                    <el-radio-group v-model="make.windowType" @change="handleCheckedCitiesChange">
                        <el-radio :key="1" label="iframe">默认(iframe)</el-radio>
                        <el-radio :key="2" label="dialog">dialog</el-radio>
                        <el-radio :key="3" label="dialog-component">dialog-component</el-radio>
                    </el-radio-group>
                </el-form-item>
            </el-col>
            <el-col :span="6"
                    v-if="make.controllerMethod.filter(v => controllerMethod.filter(v1 => v1.view).map(v1 => v1.value).includes(v)).length > 0">
                <el-form-item :label-width="120" label="子页面大小:">
                    <el-input v-model="make.windowWidth"></el-input>
                </el-form-item>
            </el-col>
        </el-row>
    </el-card>
    <el-card class="box-card">
        <el-table :data="make.fields" v-loading="fieldLoading" :header-cell-style="{textAlign:'center'}"
                  style="width: 100%">
            <el-table-column prop="field" width="180" align="center" show-overflow-tooltip
                             label="字段"></el-table-column>
            <el-table-column prop="comment" width="180" label="label">
                <template #default="scope">
                    <el-input v-model="scope.row.comment"></el-input>
                </template>
            </el-table-column>
            <el-table-column prop="form_type" width="180" label="表单类型">
                <template #default="scope">
                    <el-select style="width: 100%" clearable placeholder="请选择" v-model="scope.row.form_type">
                        <el-option v-for="type in formType" :label="type.label" :value="type.value"></el-option>
                    </el-select>
                </template>
            </el-table-column>
            <el-table-column prop="lists_type" width="180" label="列表展示类型">
                <template #default="scope">
                    <el-select style="width: 100%" clearable placeholder="请选择" v-model="scope.row.lists_type">
                        <el-option v-for="type in listsType" :label="type.title" :value="type.value"></el-option>
                    </el-select>
                </template>
            </el-table-column>
            <el-table-column prop="join_field" width="180" label="取值关系">
                <template #default="scope">
                    <el-popover
                            placement="right"
                            title="关联表字段信息"
                            :width="300"
                            trigger="click"
                    >
                        <template #reference>
                            <el-input v-model="scope.row.join_field" clearable placeholder="table:id=field"></el-input>
                        </template>
                        <div v-if="joinFields[scope.row.field]">
                            <el-table :data="joinFields[scope.row.field]">
                                <el-table-column prop="field"></el-table-column>
                                <el-table-column prop="comment"></el-table-column>
                            </el-table>
                        </div>
                        <div v-else>
                            无
                        </div>
                    </el-popover>
                </template>
            </el-table-column>
            <el-table-column prop="status_map" label="状态映射">
                <template #default="scope">
                    <el-select
                            style="width: 100%"
                            v-model="scope.row.status_map"
                            multiple
                            filterable
                            allow-create
                            default-first-option
                            :reserve-keyword="false"
                            placeholder="值=>描述"
                    >
                    </el-select>
                </template>
            </el-table-column>
        </el-table>
    </el-card>
@endsection

@section('footer')
    <script>
        VueInit.data.dirs = [];
        VueInit.data.plugins = {!! json_encode($plugins) !!};
        VueInit.data.fileAll = false;
        VueInit.data.methodAll = false;
        VueInit.data.isIndeterminate = false;
        VueInit.data.methodIsIndeterminate = false;
        VueInit.data.fieldLoading = false;
        VueInit.data.submitLoading = false;
        VueInit.data.allTables = [];
        VueInit.data.joinFields = {};
        VueInit.data.existsFiles = [];

        VueInit.data.controllerMethod = [
            {title: 'lists', value: 'lists', view: true},
            {title: 'listsData', value: 'listsData', view: false},
            {title: 'create', value: 'create', view: true},
            {title: 'store', value: 'store', view: false},
            {title: 'edit', value: 'edit', view: true},
            {title: 'update', value: 'update', view: false},
            {title: 'delete', value: 'delete', view: false},
        ];
        VueInit.data.listsType = [
            {title: '文本', value: 'text'},
            {title: '标签', value: 'tag'},
            {title: '图片', value: 'image'},
            {title: '开关', value: 'switch'},
        ];

        VueInit.data.formType = {!! json_encode(\Plugins\AdminBasic\Http\Admin\Service\DevAuxService::supportForm()) !!};

        VueInit.data.make = {
            files: [],
            controllerMethod: [],
            isCover: false,
            isPlugins: false,
            table: '',
            plugins: '',
            tableComment: '',
            dir: '',
            viewType: 'sc',
            windowType: 'iframe',
            windowWidth: '1000px',
            fields: []
        }

        VueInit.data.waitFile = [
            {sign: 'Controller', title: 'Controller'},
            {sign: 'Model', title: 'Model'},
            {sign: 'Service', title: 'Service'},
            {sign: 'FormRequest', title: 'FormRequest'},
        ];

        VueInit.methods.handleCheckAllChange = function (value) {
            if (this.fileAll) {
                this.make.files = this.waitFile.map(v => v.sign);
            } else {
                this.make.files = [];
            }
            this.isIndeterminate = false
        }

        VueInit.methods.methodHandleCheckAllChange = function (value) {
            if (this.methodAll) {
                this.make.controllerMethod = this.controllerMethod.map(v => v.value);
            } else {
                this.make.controllerMethod = [];
            }
            this.methodIsIndeterminate = false
        }

        VueInit.methods.handleCheckedCitiesChange = function (value) {
            this.fileAll = this.make.files.length === this.waitFile.length;

            if (this.make.files.length !== this.waitFile.length && this.make.files.length > 0) {
                this.isIndeterminate = true;
                return;
            }
            this.isIndeterminate = false
        }

        VueInit.methods.tableSelected = function (item) {
            this.make.tableComment = item.TABLE_COMMENT;
            this.checkFiles();
            this.getTableFields();
        };
        VueInit.methods.dirSelected = function (item) {
            this.make.dir = item;
            this.checkFiles();
        };

        VueInit.methods.methodHandleCheckedCitiesChange = function (value) {
            this.methodAll = this.make.controllerMethod.length === this.controllerMethod.length;
            if (this.make.controllerMethod.length !== this.controllerMethod.length && this.make.controllerMethod.length > 0) {
                this.methodIsIndeterminate = true;
                return;
            }
            this.methodIsIndeterminate = false;
        }

        VueInit.methods.tableQuerySearch = function (query, cb) {
            let res = [];
            for (const i in this.allTables) {
                if (this.allTables[i].TABLE_NAME.includes(query) || this.allTables[i].TABLE_COMMENT.includes(query)) {
                    res.push(this.allTables[i])
                }
            }
            return cb(res);
        }

        VueInit.methods.checkFiles = function () {
            axios({
                url: "{{ sc_route([\Plugins\AdminBasic\Http\Admin\Controller\DevAuxController::class, 'checkCURDFiles']) }}",
                params: {
                    table: this.make.table,
                    dir: this.make.dir,
                    plugins: this.make.plugins
                },
            }).then(({data}) => {
                this.existsFiles = data.data;
            });
        }

        VueInit.methods.submit = async function () {
            this.submitLoading = true;

            let res = await axios({
                url: "{{ sc_route([\Plugins\AdminBasic\Http\Admin\Controller\DevAuxController::class, 'makeCURD']) }}",
                data: this.make,
                method: 'post'
            });
            this.submitLoading = false;
            if (res.data.code !== 200) {
                this.$message.error('服务器错误.' + res.msg);
                return;
            }

            this.$message.info({
                    dangerouslyUseHTMLString: true,
                    message: res.data.data.join("<br>")
                }
            );

            this.checkFiles();
            this.getDirs();
        }

        VueInit.methods.getTableFields = async function () {
            this.fieldLoading = true;
            let data = await this.getFieldsByName(this.make.table);
            this.fieldLoading = false;
            if (data.code === 200) {
                this.joinFields = {};
                this.make.fields = [];
                data.data.map(async v => {
                    let map = [], comment = v.COLUMN_COMMENT;
                    if (/[:：]/.test(v.COLUMN_COMMENT)) {
                        let match = v.COLUMN_COMMENT.match(/(.*?)[:：](.*)/);
                        let origin = match[2];
                        map = origin.replaceAll('，', ',').split(',');
                        comment = match[1];
                    }
                    this.make.fields.push({
                        pri: v.COLUMN_KEY === "PRI",
                        field: v.COLUMN_NAME,
                        field_type: v.DATA_TYPE,
                        comment: comment,
                        form_type: this.fieldFormTypeGet(v, map),
                        lists_type: this.fieldListTypeGet(v, map),
                        status_map: map,
                        join_field: ""
                    });

                    let joinInfo = await this.joinGet(v.COLUMN_NAME);

                    if (joinInfo) {
                        this.make.fields.map(v1 => {
                            if (v1.field === v.COLUMN_NAME) {
                                v1.join_field = joinInfo
                            }
                        });
                    }
                })
            }
        }


        VueInit.methods.dirQuerySearch = function (query, cb) {
            let res = [];
            for (const i in this.dirs) {
                if (this.dirs[i].includes(query)) {
                    res.push(this.dirs[i])
                }
            }
            return cb(res);
        }

        VueInit.methods.getFieldsByName = async function (table) {
            const response = await axios({
                url: "{{ sc_route([\Plugins\AdminBasic\Http\Admin\Controller\DevAuxController::class, 'getTableFields']) }}",
                params: {
                    table: table
                }
            });

            return response.data;
        };

        VueInit.methods.fieldFormTypeGet = function (field, map) {
            if (map.length > 0) {
                return map.length > 3 ? 'select' : 'radio';
            }

            if (field.COLUMN_KEY === 'PRI') {
                return 'hidden'
            }

            if (['update_time', 'delete_time', 'create_time'].includes(field.COLUMN_NAME)) {
                return '';
            }

            if (/_id$/.test(field.COLUMN_NAME)) {
                return 'select';
            }

            if (/image/.test(field.COLUMN_NAME)) {
                return 'image'
            }

            if (/time/.test(field.COLUMN_NAME) || /date/.test(field.COLUMN_NAME)) {
                return 'datetime'
            }

            if ('text' === field.DATA_TYPE) {
                return 'editor';
            }

            return 'text';
        }

        VueInit.methods.fieldListTypeGet = function (field, map) {
            if (map.length > 0) {
                return map.length === 2 ? 'switch' : 'tag';
            }

            if (['update_time', 'delete_time'].includes(field.COLUMN_NAME)) {
                return '';
            }

            if (/image/.test(field.COLUMN_NAME)) {
                return 'image';
            }

            if (['text', 'json'].includes(field.DATA_TYPE)) {
                return '';
            }

            return 'text';
        }

        VueInit.methods.joinGet = async function (field) {
            if (!/_id$/.test(field) && field !== 'pid') {
                return ''
            }
            let table = field === 'pid' ? this.make.table : field.match(/^([a-zA-Z0-9]+)_id$/)[1];

            let data = await this.getFieldsByName(table);
            if (data.code !== 200) {
                return '';
            }
            let tableFields = data.data;

            let fields = [];
            let res = {
                table: table,
                pri: '',
                show: ''
            };

            for (const i in tableFields) {
                if (tableFields[i].COLUMN_KEY === 'PRI') {
                    res.pri = tableFields[i].COLUMN_NAME;
                }

                if (tableFields[i].DATA_TYPE.includes('char') && !res.show) {
                    res.show = tableFields[i].COLUMN_NAME;
                }

                fields.push({
                    field: tableFields[i].COLUMN_NAME,
                    comment: tableFields[i].COLUMN_COMMENT,
                });
            }

            this.joinFields[field] = fields;

            return `${res.table}:${res.pri}=${res.show}`;
        }

        VueInit.event.addHandler("created:getAllTable", function () {
            axios({
                url: "{{ sc_route([\Plugins\AdminBasic\Http\Admin\Controller\DevAuxController::class, 'getAllTables']) }}",
            }).then(({data}) => {
                if (data.code === 200) {
                    this.allTables = data.data;
                }
            })
        });

        VueInit.data.clearLoading = false;
        VueInit.data.clearExistsFiles = [];
        VueInit.methods.clearFile = function () {
            this.clearLoading = true;

            axios({
                url: "{{ sc_route([\Plugins\AdminBasic\Http\Admin\Controller\DevAuxController::class, 'CURDClear']) }}",
                method: "post",
                data: {
                    files: this.clearExistsFiles
                }
            }).then(({data}) => {
                if (data.code === 200) {
                    this.clearLoading = false;
                    this.clearExistsFiles = [];
                    this.$message.success('已清除');
                    this.checkFiles();
                }
            })
        }

        VueInit.methods.getDirs = function () {
            axios({
                url: "{{ sc_route([\Plugins\AdminBasic\Http\Admin\Controller\DevAuxController::class, 'getMakeDirs']) }}",
                params: {
                    plugins: this.make.plugins
                }
            }).then(({data}) => {
                this.dirs = data.data;
            })
        }

        VueInit.event.addHandler('created:getDirs');

        VueInit.methods.pluginsQuerySearch = function (search, cb) {
            let res = [];
            if (!search) return cb(this.plugins);
            for (let i = 0; i < this.plugins.length; i++) {
                if (this.plugins[i].name.includes(search)) {
                    res.push(this.plugins[i]);
                }
            }
            return cb(res);
        }

        VueInit.methods.pluginsSelected = function (item) {
            this.make.plugins = item.name;
            this.getDirs();
        }
        VueInit.methods.pluginsChange = function (item) {
            this.make.plugins = item;
            this.getDirs();
        }
        VueInit.methods.isPluginsChange = function (item) {
            if (!item) {
                this.make.plugins = '';
                this.getDirs();
            }
        }
    </script>
@endsection